home *** CD-ROM | disk | FTP | other *** search
- C dili - 5. Konu
-
-
- Fonksiyonlar ve degiskenler
-
- KARETOPL.C:
- ================================================================
-
- int toplam; /* Global degisken */
-
- main()
- {
- int index;
-
- baslik(); /* Baslik isimli fonksiyonu cagirir */
-
- for (index = 1;index <= 7;index++)
- kare(index); /* Bu, kare fonksiyonunu cagirir. */
-
- bitis(); /* Bu da, bitis isimli fonksiyonu cagirir */
- }
-
- baslik() /* Bu fonksiyonun tanimidir */
- {
- toplam = 0; /* "Toplam" isimli degiskene 0 degeri atanir.. */
- printf("Bu, kare programinin basligidir\n\n");
- }
-
- kare(rakam) /* Bu, kare fonksiyonunun baslangicidir */
- int rakam;
- {
- int karesi; /* Yerel degisken tanimlaniyor */
-
- karesi = rakam * rakam ; /* Karesini olusturuyor. */
- toplam += karesi; /* Bulunan deger, toplama ekleniyor */
- printf("%d nin karesi %d dir.\n",rakam,karesi);
- }
-
- bitis() /* Bitis fonksiyonu tanimlaniyor. */
- {
- printf("\nKarelerin toplami: %d dir..\n",toplam);
- }
- ================================================================
-
-
- KARETOPL.C isimli programa bir bakin. Bu program, fonksiyonlu ilk
- programimiz. Goreceginiz gibi C de fonksiyon tanimlamak o kadar kolaydir
- ki, programlarin fonksiyonlara parcalanmasi neredeyse istemeden olur.
- Aslinda, biz fonksiyonlari kullanip duruyorduk, ornegin kullandigimiz
- printf komutu, bir fonksiyondur. Printf fonksiyonu, derleyici ile gelen
- fonksiyon kutuphanesinin bir parcasidir.
-
- Bu programin calisan kismina bir bakin. baslik() isimli bir satir ile
- basliyor. Iste C de, herhangi bir fonksiyon, bu sekilde cagirilir: ismi,
- parantez, ve sayet varsa bu fonksiyona gonderilmesi istenen degerler
- yazilir. Programin calismasi bu satira gelince, baslik isimli fonksiyona
- atlanir, ve buradaki islemler yapilir. Bitince, program geri doner, ve
- ana programda kaldigi yerden isleme devam eder, ve "for" dongusune gelir.
- Burada, yedi kere "kare" isimli bir fonksiyonu cagirir, daha sonra "bitis"
- fonksiyonunu cagirir ve program sona erer.
-
- FONKSIYONUN TANIMLANMASI
-
- main'den sonra ayni main'in ozelliklerini tasayan bir program
- goreceksiniz. Sadece bunun ismi "baslik()" olarak tanimlanmistir. Bu
- basligin ilk satirinda "toplam" degiskeninin degeri 0 a atanir, ve bir
- baslik satiri yazilir. Dikkat ederseniz, "toplam" degiskenini,
- fonksiyonlarin disinda, programin basinda tanimlamistik. Bu sekilde
- tanimlanan bir degisken, o programdaki herhangi bir fonksiyondan
- cagirilabilir. Bu tip degiskenlere "global" denir.
-
- Bu iki satiri main() in icine de koymamiz mumkundur. Bu ornek sadece
- fonksiyonlarin kullanimini gostermektedir.
-
- FONKSIYONA DEGER GECIRMEK
-
- Ana programda, "for" dongusunde, "index++" deyimini goruyorsunuz. Ilk
- olarak gecen konuda ogrendigimiz birer birer arttirma metoduna alismaya
- bakin, cunku C programlarinda cok karsilasacaksiniz.
-
- "kare" isimli fonksiyonu cagirirken, bir yenilik kattik. Yani, parantez
- icindeki "index" deyimini. Bu da derleyiciye, o fonksiyona gidince,
- "index" in o andaki degerini de beraberimizde goturmek istedigimizi
- belirtir. "Kare" isimli fonksiyonun basligina baktigimizda ise,
- parantezler icinde bir baska degisken ismi goruyoruz: "rakam." Ana
- programdan "kare(index)" dedigimizde gelen index'in degerine, bu fonksiyon
- icinde 'rakam' diyecegimizi belirtiyoruz. Buna rakam demek yerine
- istedigimiz herhangi bir ismi verebilirdik - C nin degisken isim
- kurallarina uymasi sarti ile. Fonksiyon, ona ne tip bir deger
- gecirilecegini bilmesi icinde, hemen alt satirda, "int rakam" diyerek,
- gelecek bu degerin bir integer olacagini belirtiyoruz.
-
- Kume isaretinden sonra, "int karesi" deyimi ile, sadece bu fonksiyonun
- icinde tanimli olan bir degisken daha tanimlandigini goruyoruz. Bundan
- sonra, "karesi" degiskenine 'rakam' in karesini atiyoruz, ve "toplam"
- degiskenine de "karesi" degiskeninin degerini ekliyoruz.
-
- BIR FONKSIYONA DEGER ATAMA HAKKINDA DAHA BILGI
-
- Aslinda "index" in degerini fonksiyona gecirdigimizde, anlattigimdan biraz
- daha fazla sey oldu. Gercekte, "index" in degerini gecirmedik bu
- fonksiyona, o degerin bir kopyasini gecirdik. Bu sayede, "index" in asil
- degeri, fonksiyon tarafindan kazara zarar goremez. "rakam" isimli
- degiskenimizi fonksiyon icinde istedigimiz gibi degistirebilirdik, fakat
- ana programa geri dondugumuzde, "index" in degeri yine ayni kalirdi.
-
- Boylece, degiskenin degerinin zarar gormesini onlemis oluyoruz, fakat ayni
- zamanda, ana programa bir deger dondurmemize de mani oluyoruz. Pointers
- kisimina gelince, cagiran fonkisyona degeri dondurmek icin, iyi tanimli
- bir metod gorecegiz. O zamana kadar ana programa deger dondurmenin yegane
- yolu, global degiskenler kullanaraktir. Global degiskenlerden biraz
- bahsetmistik, bu konu icersinde, daha da bahsedecegiz.
-
- Programa devam ederek, bitis() isimli bir fonksiyonun cagirilisina
- geliyoruz. Bu cagirma da, hicbir yerel degiskeni olmayan fonksiyonu
- cagirir. "toplam" degiskeninin degerini yazdiktan sonra ana kesime donen
- program, yapacak baska birsey olmadigini gorunce durur.
-
- UFAK BIR YALANI ITIRAF ETME ZAMANI
-
- Biraz once size bir fonksiyondan bir deger dondurmek icin yegane yolun
- global degiskenler ile olabilecegini soylemistim. Fakat bir baska metod
- daha var. Lutfen KARELER.C isimli programa bakin...
-
- KARELER.C:
- =====================================================================
-
- main() /* Ana program burada. */
- {
- int x,y;
-
- for(x = 0;x <= 7;x++) {
- y = squ(x); /* x*x i hesaplayalim.. */
- printf("%d nin karesi %d dir...\n",x,y);
- }
-
- for (x = 0;x <= 7;++x)
- printf("%d nin karesi %d dir...\n",x,squ(x));
- }
-
- squ(in) /* Bir rakamin karesini bulan fonksiyon */
- int in;
- {
- int kare;
-
- kare = in * in;
- return(kare); /* Yeni buldugumuz deger donduruluyor.. */
- }
-
- =====================================================================
-
- Bu program, tek bir deger dondurmenin kolay oldugunu gosteriyor. Fakat,
- birden fazla deger dondurmek icin, baska metodlara gerek oldugunu
- hatirlamanizda fayda var.
-
- ana programda, iki tane tamsayi degiskeni tanimliyoruz, ve 8 kere islenen
- bir "for" dongusu baslatiyoruz. Dongudeki ilk satir, "y = squ(x);", yeni
- ve tuhaf gorunuslu bir satir. Onceki programlarda gordugumuz gibi, squ(x)
- kisimi, squ isimli fonksiyonu, x parametresi ile cagirmaktadir. Fonksiyona
- baktigimizda, bu gecen degiskenin orada 'in' isminde oldugunu, ve kare
- ismindeki yerel degiskene, gecirdigimiz degerin karesinin atandigini
- goruyoruz. Daha sonra, yeni "return" komutunu goruyoruz. Parantezler
- icindeki bu deger, fonksiyonun kendisine atanir, ve ana programa bu deger
- dondurulur. Yani, "squ(x)" fonksiyonu, x in karesine atanir, ve bu deger,
- ana programa atanir. Ornegin, x in degeri 4 ise, y nin degeri, "y=squ(x)"
- satirindan sonra 16 olacaktir.
-
- Bir baska dusunme sekli de, "squ(x)" sozcugunu, "x" in karesi degerinde bir
- degisken olarak dusunmektir. Bu yeni degisken de, degiskenlerin
- kullanildigi herhangi bir yerde kullanilabilir. Baska bir degisken olarak
- gormeye bir ornek olarak bu programda ikinci bir dongu vardir. Burada,
- y degiskenine atamak yerine, printf'in icinde, bu fonksiyonu cagiriyoruz.
-
- Bir fonksiyondan donecek degiskenin tipi, derleyiciye bildirilmelidir.
- Fakat, bizim yaptigimiz gibi sayet belirtmezsek, derleyici donecek degerin
- tam sayi (integer) olacagini kabul edecektir. Baska tiplerin tanimlanmasini
- ise, bundan sonraki programda gorecegiz..
-
-
- KAYAR NOKTA FONKSIYONLARI
-
- KAYARKAR.C:
- ================================================================
-
- float z; /* Bu bir global degiskendir */
-
- main()
- {
- int index;
- float x,y,sqr(),glsqr();
-
- for (index = 0;index <= 7;index++){
- x = index; /* int'i float yapalim */
- y = sqr(x); /* x'in karesini alalim.. */
- printf("%d in karesi %10.4f dir.\n",index,y);
- }
-
- for (index = 0; index <= 7;index++) {
- z = index;
- y = glsqr();
- printf("%d in karesi %10.4f dir.\n",index,y);
- }
- }
-
- float sqr(deger) /* float'in karesini al, float dondur. */
- float deger;
- {
- float karesi;
-
- karesi = deger * deger;
- return(karesi);
- }
-
- float glsqr() /* float'in karesini al, float dondur. */
- {
- return(z*z);
- }
- ================================================================
-
- KAYARKAR.C isimli programa bir bakin. Ilk once daha sonra kullanacagimiz
- bir global degisken tanimlamak ile basliyor. Programin "main" kisiminda,
- bir tamsayi degiskeni tanimlaniyor. Bunun altinda, iki tani tamsayi
- degiskeni, iki tane de tuhaf gorunuslu tanimlamalar var. "sqr()" ve
- "glsqr()" isimli iki fonksiyon gibi gorunuyorlar, ve oyleler. Bu, C
- dilinde "int" yani tamsayi dan baska birsey dondurecek bir fonksiyonun
- (float mesela) resmi sekilde tanimlanmasidir. Bu derleyiciye, bu iki
- fonksiyondan bir deger donunce, bu degerin float olacagini bildiriyor.
-
- Simdi programin ortasinda yer alan "sqr" fonksiyonuna bir bakin. Burada
- fonksiyonun isminin basinda bir "float" sozcugu goreceksiniz. Bu
- derleyiciye herhangi bir yerden bu fonksiyon cagirilinca, donecek degerin
- float olacagini bildiriyor. Simdi bu fonksiyon, ana programdaki cagirma
- ile uyumludur. Bunun altinda, "float deger" satirini goruyorsunuz. Bu da,
- bu fonksiyona, cagiran tarafindan gecirilecek degerin, bir "float" yani
- kayar nokta olacagini bildirir.
-
- Bundan sonraki fonksiyon "glsqr" da, bir kayar nokta donduruyor, fakat o,
- input icin global bir degikeni (z degiskenini) kullaniyor. Ayrica, yeni
- bir degisken tanimlamadan, karesini almayi "return" komutunun icinde
- yapiyor.
-
- DEGISKENLERIN ALANI
-
- ALAN.C:
- ================================================================
- int say; /* Bu bir global degiskendir. */
-
- main()
- {
- register int index; /* Bu degisken sadece "main" icinde kullanilabilir */
-
- baslik_1();
- baslik_2();
- baslik_3();
- /* bu programin ana "for" dongusu */
- for (index = 8;index > 0;index--)
- {
- int birsey; /* Bu degisken sadece bu kume isaretleri arasinda tanimli */
-
- for (birsey = 0;birsey <= 6;birsey++)
- printf("%d ",birsey);
-
- printf(" index simdi: %d oldu.\n",index);
- }
- }
-
- int sayac; /* Bu degisken bu noktadan sonra kullanilabilir. */
-
- baslik_1()
- {
- int index; /* Bu degisken sadece baslik_1 icinde tanimli */
-
- index = 23;
- printf("Baslik_1 deki degeri %d\n",index);
- }
-
- baslik_2()
- {
- int say; /* Bu degisken sadece baslik_2 icinde gecerli */
- /* ayni isimli global degiskenin yerini alir.. */
-
- say = 53;
- printf("Baslik_2 deki degeri %d\n",say);
- sayac = 77;
- }
-
- baslik_3()
- {
- printf("Baslik_3 deki degeri ise %d\n",sayac);
- }
- ================================================================
-
- Ilk tanimlanan degisken "say", butun fonksiyonlardan once tanimlandigi
- icin, herhangi biri tarafindan cagirilabilir, ve daima erisilebilir. Daha
- sonra, "sayac" isimli bir degisken tanimliyoruz. Bu da global bir
- degiskendir, fakat ana programdan sonra tanimlandigi icin, ana program
- tarafindan kullanilamaz. Global bir degisken, fonksiyonlarin disinda
- tanimlanan degiskenlere denir. Bu tip degiskenlere dissal degiskenler adi
- da verilebilir.
-
- Ana programa geri donerek, "index" isimli degiskenin tanimina bakalim. Su
- an icin "register" sozcugunu goz onune almayin. Bu degisken "otomatik" bir
- degiskendir, yani o fonksiyon cagirildiginda olusur, ve fonksiyondan
- cikinca kaybolur. Ana program baska fonksiyonlari cagirdiginda bile daima
- calisir oldugundan, burada pek manasi yoktur. Tanimlanan diger bir
- degisken de, "birsey" degiskenidir. Bu degisken, sadece "for" dongusunun
- icinde tanimlidir, ve baska bir yerden erisilemez. Herhangi bir kume
- dongusunun basina, degisken tanimlamalari konulabilir. Kumeden cikinca, bu
- degisken tanimsiz olacaktir.
-
- OTOMATIK DEGISKENLER HAKKINDA...
-
- Baslik_1'e bir bakin. "index" isimli bir degisken kullaniyor. Bu
- degiskenin ana programdaki "index" ile arasinda, ikisinin de otomatik
- degisken olmasi disinda hicbir bag yoktur. Program, bu fonksiyonu
- islemezken, bu degisken yoktur bile. Baslik_1 cagirildiginda, bu degisken
- yaratilir, ve baslik_1 bitince de bu degisken silinir. Fakat bu, ana
- programdaki ayni isimli degiskenin degerini hic etkilemez, cunku ayri
- nesnelerdir.
-
- Yani otomatik degiskenler, gerektiginde yaratilirlar, ve isleri bitince de
- silinirler. Hatirlamaniz gereken bir nokta da, bir fonksiyon birden fazla
- kere cagirildiginda, otomatik degiskenlerin eski degerleri saklanmaz, yeni
- bastan deger atanmalari gerekir.
-
- STATIK DEGISKENLER ?
-
- Bir baska degisken tipi ise, statik degiskenlerdir. Degiskeni tanimlarken
- basina "static" sozcugunu koyarak, o degisken yada degiskenler,
- fonksiyonun tekrar tekrar cagirilmasinda, eski degerlerini tutarlar.
-
- Ayni sozcugu bir global degiskenin onune koyarak, o degiskenin sadece o
- kutuk icindeki fonksiyonlara tanimli olmasini saglayabiliriz. Bundanda
- anlayacaginiz gibi, birkac parcadan olusan kutukler arasinda global
- degiskenlerin tanimlanmasi mumkundur. Bunu 14. konuda daha iyi gorecegiz.
-
- AYNI ISMI TEKRAR KULLANMAK
-
- baslik_2 ye bir bakin. Burada "say" isimli degiskenin tekrar
- tanimlandigini ve 53 degerini aldigini goruyoruz. Global olarak
- tanimlanmasina karsin, ayni isimde bir otomatik degisken tanimlamak
- mumkundur. Bu degisken tumuyle yeni bir degiskendir, ve global olarak,
- programin basinda tanimlanan "say" ile arasinda hicbir baglanti yoktur. Bu
- sayede kafanizda "acaba global isimlerle karisirmi" sorusu olmadan
- fonksiyon yazabilirsiniz.
-
- REGISTER DEGISKENLERI NEDIR
-
- Sozumu tutarak, register degiskenine donelim. Bir bilgisayar bilgiyi
- hafizada yada registerlerde tutabilir. Register sahasina erisim, hafizaya
- erisimden cok daha hizlidir, fakat programcinin kullanabilecegi az sayida
- register vardir. Bazi degiskenlerin program tarafindan cok kullanilacagini
- dusunuyorsaniz, o degiskeni "register" olarak tanimlayabilirsiniz.
- Bilgisayar ve derleyici tipinize gore, bir yada birkac degiskeni bu
- sekilde tanimlayabilirsiniz. Cogu derleyicilerin hic register degiskenleri
- yoktur, ve "register" sozcugunu goz onune almadan derleme yaparlar.
-
- Register degiskenleri, sadece tamsayi ve karakter tipi degiskenler ile
- kullanilabilir. Sectiginiz derleyiciye gore, unsigned, long yada short
- tipleride register olabilir.
-
- DEGISKENLERI NEREDE TANIMLAYALIM
-
- Bir fonksiyona parametre olarak gecirilmis degiskenler varsa, bunlarin
- tanimi, fonksiyon isminden sonra, ve acik kume isaretinden once
- yapilmalidir. Fonksiyonda kullanilan diger degiskenler ise, fonksiyonun
- basinda, hemen acik kume isaretinden sonra tanimlanir.
-
- STANDART FONKSIYON KUTUPHANESI
-
- Her derleyici, icinde bircok fonksiyon olan bir kutuphane ile birlikte
- gelir. Bunlar genellikle giris/cikis islemleri, karakter ve katar isleme,
- ve matemetiksel fonksiyonlari icerir. Bunlarin cogunu sonraki konularda
- gorecegiz.
-
- Bunun disinda, cogu derleyicinin, standart olmayan, ve kullandiginiz
- bilgisayarin ozelliklerini kullanan, ilave fonksiyonlari vardir. Ornegin,
- IBM-PC ve uyumlular icin, BIOS servislerini kullanan fonksiyonlar
- sayesinde, isletim sistemine komutlar vermeyi, yada ekrana direk yazmayi
- saglayan fonksiyonlar olabilir.
-
- RECURSION NEDIR ?
-
- RECURS.C:
- ================================================================
-
- main()
- {
- int index;
-
- index = 8;
- geri_say(index);
- }
-
- geri_say(rakam)
- int rakam;
- {
- rakam--;
- printf("rakam degeri %d dir.\n",rakam);
- if (rakam > 0)
- geri_say(rakam);
- printf("Simdi rakam %d oldu..\n",rakam);
- }
-
- ================================================================
-
- Recursion, ilk karsilasildiginda cok korkutucu gorunen bir kavramdir.
- Fakat RECURS.C isimli programa bakarsaniz, recursion'un butun zorlugunu
- yenebiliriz. Aslinda fazla basit ve dolayisi ile aptal olan bu program,
- bize recursion'un kullanimini gostermesi bakimindan cok yararlidir.
-
- Recursion, kendini cagiran bir fonksiyondan baska birsey degildir. Yani,
- bitmek icin bir kontrol mekanizmasina ihtiyaci olan bir dongudur.
- Karsinizdaki programda "index" degiskeni 8 e atanir, ve "geri_say"
- fonksiyonunun parametresi olarak kullanilir. Bu fonksiyon da, bu
- degiskenin degerini teker teker azaltir, ve bize bu degeri gosterir. Sonra
- tekrar kendisini cagirir, degeri bir kez daha azalir, tekrar, tekrar..
- Sonunda deger sifira ulasir, ve dongu artik kendini cagirmaz. Bunun
- yerine, daha onceki cagirmada kaldigi yere geri doner, tekrar geri doner,
- en sonunda ana programa geri doner, ve program sona erer.
-
-
- NE OLDU ?
-
- Fonksiyon kendisini cagirdiginda, butun degiskenlerini,ve cagirilan
- fonksiyonun islemesi bittiginde donmesi gereken yeri hafizaya sakladi.
- Bir dahaki sefere kendinin tekrar cagirdiginda, yine ayni seyi yapti, ta
- ki kendisini tekrar cagirmasi bitene kadar. Daha sonra tekrar bu
- bilgileri, ayni koyus sirasi ile geri okudu.
-
- Hatirlamaniz gereken nokta, recursion'un bir noktada bitmesi gerektigidir,
- sayet sonsuz bir donguye girerseniz, bilgisayarin hafizasi bitecek ve bir
- hata mesaji cikacaktir.
-
- ODEVLER
-
- 1. Daha once yazdigimiz Santigrad'dan Fahrenheit'a karsilik tablosundaki
- derece hesaplamasini bir fonksiyona geciriniz.
- 2. Ekrana isminizi 10 kere yazan bir program yaziniz. Yazma isini yapmak
- icin bir fonksiyon cagiriniz. Daha sonra bu fonksiyonu main() in basina
- alarak, derleyicinin bunu kabul edip etmedigini kontrol ediniz.